package gcp;

import gcp.enums.Sexo;

import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;

/**
 * Pessoa<br>
 * Entidade que representa uma pessoa.
 * @version 1.5 13/10/2009
 */
public class Pessoa implements Serializable {

    private static final long serialVersionUID = 1L;
    private String nome;
    private String sobrenome;
    private Sexo sexo;
    private Date dataNascimento;
    private String endereco = "";
    private String email = "";
    private String telefone = "";
    private String celular = "";

    /**
     * Cria o objeto Pessoa.
     */
    public Pessoa() {}

    /**
     * Cria o objeto Pessoa.
     * @param nome Nome da pessoa.
     * @param sobrenome Sobrenome da pessoa.
     * @param sexo Sexo da pessoa.
     * @throws Exception Lancada caso algum parametro seja nulo ou vazio.
     */
    public Pessoa(String nome, String sobrenome, Sexo sexo) throws Exception {
        if (nome == null || nome.isEmpty())
            throw new Exception("Nome não pode ser nulo.");
        if (sobrenome == null || sobrenome.isEmpty())
            throw new Exception("Sobrenome não pode ser nulo.");
        this.nome = nome;
        this.sobrenome = sobrenome;
        this.sexo = sexo;
    }

    /**
     * Retorna o nome da pessoa.
     * @return nome O nome da pessoa.
     */
    public String getNome() {
        return nome;
    }

    /**
     * Atualiza o nome da pessoa para um novo passado como argumento.
     * @param nome O nome da pessoa.
     * @throws Exception Lancada caso o parametro seja nulo ou vazio.
     */
    public void setNome(String nome) throws Exception {
        this.nome = nome;
    }

    /**
     * Retorna o sobrenome da pessoa.
     * @return sobrenome O sobrenome da pessoa.
     */
    public String getSobrenome() {
        return sobrenome;
    }

    /**
     * Atualiza o sobrenome da pessoa pra o passado como argumento.
     * @param sobrenome O sobrenome da pessoa.
     * @throws Exception Lancada caso o parametro seja nulo ou vazio.
     */
    public void setSobrenome(String sobrenome) throws Exception {
        this.sobrenome = sobrenome;
    }

    /**
     * Retorna o sexo da pessoa.
     * @return sexo O sexo da pessoa.
     */
    public Sexo getSexo() {
        return sexo;
    }

    /**
     * Atualiza o sexo da pessoa para o passado como argumento.
     * @param sexo O sexo da pessoa.
     */
    public void setSexo(Sexo sexo) {
        this.sexo = sexo;
    }

    /**
     * Retorna a idade da pessoa, baseada na data de nascimento.
     * @return idade A idade da pessoa.
     */
    public int getIdade() {
        if (dataNascimento == null)
            return 0;
        int idade = 0;
        Calendar calendarioNascimento = Calendar.getInstance();
        Calendar calendarioAtual = Calendar.getInstance();
        calendarioNascimento.setTime(dataNascimento);
        calendarioAtual.setTime(new Date());
        int anoNascimento = calendarioNascimento.get(Calendar.YEAR);
        int anoAtual = calendarioAtual.get(Calendar.YEAR);
        int mesNascimento = calendarioNascimento.get(Calendar.MONTH);
        int mesAtual = calendarioAtual.get(Calendar.MONTH);
        int diaDoNascimento = calendarioNascimento.get(Calendar.DAY_OF_MONTH);
        int diaAtual = calendarioAtual.get(Calendar.DAY_OF_MONTH);
        idade = anoAtual - anoNascimento;
        if ((mesAtual < mesNascimento)
                || ((mesAtual == mesNascimento) && (diaAtual < diaDoNascimento))) {
            idade -= 1;
        }
        return idade;
    }

    /**
     * Retorna a data de nascimento de uma Pessoa.
     * @return dataNascimento A data de Nascimento da pessoa.
     */
    public Date getDataNascimento() {
        return dataNascimento;
    }

    /**
     * Atualiza a data de nascimento de uma Pessoa para passada como parametro.
     * @param dataNascimento A data de nascimento de uma Pessoa.
     */
    public void setDataNascimento(Date dataNascimento) {
        this.dataNascimento = dataNascimento;
    }

    /**
     * Retorna o email da Pessoa.
     * @return email O email da Pessoa.
     */
    public String getEmail() {
        return email;
    }

    /**
     * Atualiza o email da Pessoa para o passado como argumento.
     * @param email O email da Pessoa.
     */
    public void setEmail(String email) {
        this.email = email;
    }

    /**
     * Retorna o endereco da Pessoa.
     * @return O endereco da Pessoa.
     */
    public String getEndereco() {
        return endereco;
    }

    /**
     * Atualiza o endereco da Pessoa para o passado como argumento.
     * @param endereco O endereco da Pessoa.
     */
    public void setEndereco(String endereco) {
        this.endereco = endereco;
    }

    /**
     * Retorna uma String que representa o numero do telefone da Pessoa.
     * @return O telefone da Pessoa.
     */
    public String getTelefone() {
        return telefone;
    }

    /**
     * Atualiza o telefone da Pessoa para o passado como parametro.
     * @param telefone O telefone da Pessoa a ser atualizado.
     */
    public void setTelefone(String telefone) {
        this.telefone = telefone;
    }

    /**
     * Retorna uma String que representa o numero do celular da Pessoa.
     * @return celular O numero do celular da Pessoa.
     */
    public String getCelular() {
        return celular;
    }

    /**
     * Atualiza o celular da Pessoa para o passado como parametro.
     * @param celular O celular da Pessoa a ser atualizado.
     */
    public void setCelular(String celular) {
        this.celular = celular;
    }

    /**
     * Verifica se Pessoa eh igual ao objeto passado como parametro.
     * @param objeto O objeto a ser comparado.
     * @return true, em caso de semelhanca, False caso contrario.
     */
    @Override
    public boolean equals(Object objeto) {
        if (!(objeto instanceof Pessoa)) {
            return false;
        }
        Pessoa outro = (Pessoa) objeto;
        return getNome().equals(outro.getNome())
                && getSobrenome().equals(outro.getSobrenome());
    }

    /**
     * Retorna um hashCode para Pessoa.
     * @return hashCode para Pessoa.
     */
    @Override
    public int hashCode() {
        int valor = 0;
        if (getNome() != null) {
            valor = getNome().hashCode() + getSobrenome().hashCode();
        }
        return valor;
    }

    /**
     * Retorna uma representacao String para a Pessoa.
     * @return String que representa a Pessoa.
     */
    @Override
    public String toString() {
        return "Nome: " + getNome() + " " + getSobrenome() + ". Idade: "
                + getIdade() + ". Sexo: " + getSexo() + ".";
    }
}